<?php

namespace addons\litestore\model;

use app\admin\model\Useraddress;
use app\admin\model\Userscorelog;
use think\Exception;
use think\Model;
use think\Db;

class Litestoreorder extends Model
{
    // 表名
    protected $name = 'litestore_order';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';

    // 追加属性
    protected $append = [
        'pay_status_text',
        'pay_time_text',
        'freight_status_text',
        'freight_time_text',
        'receipt_status_text',
        'receipt_time_text',
        'order_status_text',
        'creattime_text',
    ];

    public function cancel($user_id, $order_id)
    {
        if ($this['pay_status'] === '20') {
            $this->error = '已付款订单不可取消';
            return false;
        }
        $goods = $this['goods'];
        $this->backGoodsStock($goods);

        $order = self::get([
            'id' => $order_id,
            'user_id' => $user_id,
            'order_status' => ['<>', '20']
        ]);

        $userScoreLogModel = new Userscorelog();
        if($order['order_type'] == 'jf' && $order['pay_status'] === '10'){

            $scoreArray = array();
            $scoreArray['user_id'] = $user_id;
            $scoreArray['score'] = $order['total_score'];
            $scoreArray['log_type'] = 4;
            $scoreArray['desc'] = "订单取消退还" . $order['total_score'] ;
            $scoreArray['createtime'] = time();
            $scoreArray['order_id'] = $order_id;
            $userScoreLogModel->insert($scoreArray);
        }



        return $order->save([
            'order_status' => '20'
        ]);
    }

    private function backGoodsStock(&$goodsList)
    {
        $goodsSpecSave = [];
        foreach ($goodsList as $goods) {
            // 下单减库存
            if ($goods['deduct_stock_type'] === '10') {
                $goodsSpecSave[] = [
                    'goods_spec_id' => $goods['goods_spec_id'],
                    'stock_num' => ['inc', $goods['total_num']]
                ];
            }
        }
        if (!empty($goodsSpecSave)) {
            // 更新商品规格库存
            return (new Litestoregoodsspec)->isUpdate()->saveAll($goodsSpecSave);
        }
        return true;
    }

    public function finish($user_id, $order_id)
    {
        if (!$order = self::get([
            'id' => $order_id,
            'user_id' => $user_id,
            'order_status' => ['<>', '20']
        ])) {
            throw new BaseException(['msg' => '订单不存在']);
        }
        if ($order['freight_status'] === '10' || $order['receipt_status'] === '20') {
            $order->error = '该订单不合法';
            return false;
        }
        return $order->save([
            'receipt_status' => '20',
            'receipt_time' => time(),
            'order_status' => '30'
        ]);
    }


    public function finish2($order_id)
    {
        if (!$order = self::get([
            'id' => $order_id,
            'order_status' => ['<>', '20']
        ])) {
            throw new BaseException(['msg' => '订单不存在']);
        }
        if ($order['freight_status'] === '10' || $order['receipt_status'] === '20') {
            $order->error = '该订单不合法';
            return false;
        }
        return $order->save([
            'receipt_status' => '20',
            'receipt_time' => time(),
            'order_status' => '30'
        ]);
    }

    public function checkGoodsStatusFromOrder($goodsList)
    {
        foreach ($goodsList as $goods) {
            //商品是否下架
            if ($goods['goods']['goods_status'] !== '10') {
                $this->setError('很抱歉，商品 [' . $goods['goods_name'] . '] 已下架');
                return false;
            }
            //付款减库存
            if ($goods['deduct_stock_type'] === '20' && $goods['spec']['stock_num'] < 1) {
                $this->setError('很抱歉，商品 [' . $goods['goods_name'] . '] 库存不足');
                return false;
            }
        }
        return true;
    }

    public function getList($user_id)
    {
        return $this->with(['goods'])
            ->where('user_id', '=', $user_id)
            ->where('order_status', '<>', '20')
            ->order(['createtime' => 'desc'])->limit(50)
            ->select();
    }

    public function getOrderDetail($order_id, $user_id)
    {
        if (!$order = self::get([
            'id' => $order_id,
        ])) {
            throw new BaseException(['msg' => '订单不存在']);
        }

        $litestoreordergoods = new Litestoreordergoods();
        $goods = $litestoreordergoods->where('order_id', $order_id)->select();
        $order['goods'] = $goods;
        $litestoreorderaddress = new Litestoreorderaddress();
        $address = $litestoreorderaddress->where('order_id', $order_id)->find();
        $order['address'] = $address;

        $goodsList = [];
        foreach ($order['goods'] as $index => $item) {
            $item['image'] = cdnurl(explode(",", $item['images'])[0], true);
            $item['sku_image'] = $item['spec']['spec_image'] == '' ? '' : cdnurl($item['spec']['spec_image'], true);
            $goodsList[] = $item;
        }
        $order['goods'] = $goodsList;

        return $order;
    }

    public function payDetail($order_no)
    {
        return self::get(['order_no' => $order_no, 'pay_status' => 10], ['goods']);
    }

    public function getCart($user_id)
    {
        $model = new CacheCart($user_id);
        return $model->getList($user_id);
    }

    public function CarclearAll($user_id)
    {
        $Card = new CacheCart($user_id);
        $Card->clearAll();
    }

    public function getExpressPrice($city_id, $goods_id, $goods_num, $goods_sku_id)
    {
        $goods = Wxlitestoregoods::detail($goods_id);
        $goods['goods_sku'] = $goods->getGoodsSku($goods_sku_id);
        // 商品总重量
        $goods_total_weight = bcmul($goods['goods_sku']['goods_weight'], $goods_num, 2);
        $expressPrice = $goods['freight']->calcTotalFee($goods_num, $goods_total_weight, $city_id);
        return $expressPrice;
    }

    public function getBuyNow($address_id, $goods_id, $goods_num, $goods_sku_id)
    {

        $wxlitestoregoods = new Wxlitestoregoods();
        // 商品信息
        $goods = $wxlitestoregoods::detail($goods_id);
        $goods['show_error'] = 0;
        // 判断商品是否下架
//        if ($goods['goods_status'] !== '10') {
//            $goods['show_error'] = 1;
//            $goods['show_error_text'] = '已下架';
//            $this->setError('很抱歉，商品信息不存在或已下架');
//        }
        // 商品sku信息

        $sku = $wxlitestoregoods->getGoodsSku($goods_sku_id);
        error_log("======goods_sku===".json_encode($sku));
        $goods['goods_sku'] = $sku;

        // 判断商品库存
        if ($goods_num > $goods['goods_sku']['stock_num']) {
            $goods['show_error'] = 2;
            $goods['show_error_text'] = '库存不足';
            $this->setError('很抱歉，商品库存不足');
        }
        // 商品单价
        $goods['goods_price'] = $goods['goods_sku']['goods_price'];
        // 商品总价
        $goods['total_num'] = $goods_num;
        $goods['total_price'] = $totalPrice = bcmul($goods['goods_price'], $goods_num, 2);
        // 商品总重量
        $goods_total_weight = bcmul($goods['goods_sku']['goods_weight'], $goods_num, 2);
        // 当前用户收货城市id

        $userAddressModel = new Useraddress();
        $defaultcity = $userAddressModel->where('id',$address_id)->find();
//        $cityId = $defaultcity ? $defaultcity['cityid'] : null;
//        // 是否存在收货地址
//        $exist_address = $defaultcity;
//        // 验证用户收货地址是否存在运费规则中
//        if (!$intraRegion = $goods['freight']->checkAddress($cityId)) {
//            $exist_address && $this->setError('很抱歉，您的收货地址不在配送范围内');
//        }
//        // 计算配送费用
//        $expressPrice = $intraRegion ?
//            $goods['freight']->calcTotalFee($goods_num, $goods_total_weight, $cityId) : 0;
        $orderNo = $this->orderNo();



        return [
            'goods_list' => [$goods],               // 商品详情
            'order_total_num' => $goods_num,        // 商品总数量
            'order_total_price' => $totalPrice,    // 商品总金额 (不含运费)
            'pay_price' => $totalPrice,  // 实际支付金额
            'address' => $defaultcity,  // 默认地址
            'express_price' => 0,    // 配送费用
            'has_error' => $this->hasError(),
            'error_msg' => $this->getError(),
            'order_no' => $orderNo
        ];
    }

    public function getMoneyBuyNow($address_id, $user_id, $goods_id, $goods_num, $goods_sku_id, $pay_type)
    {
        // 商品信息
        $goods = Wxlitestoregoods::detail($goods_id);
        $goods['show_error'] = 0;
        // 判断商品是否下架
        if ($goods['goods_status'] !== '10') {
            $goods['show_error'] = 1;
            $goods['show_error_text'] = '已下架';
            $this->setError('很抱歉，商品信息不存在或已下架');
        }
        // 商品sku信息
        $goods['goods_sku'] = $goods->getGoodsSku($goods_sku_id);


        // 判断商品库存
        if ($goods_num > $goods['goods_sku']['stock_num']) {
            $goods['show_error'] = 2;
            $goods['show_error_text'] = '库存不足';
            $this->setError('很抱歉，商品库存不足');
        }
        // 商品单价
        $goods['goods_price'] = $goods['goods_sku']['goods_price'];
        // 商品总价
        $goods['total_num'] = $goods_num;
        $goods['total_price'] = $totalPrice = bcmul($goods['goods_price'], $goods_num, 2);
        // 商品总重量
        $goods_total_weight = bcmul($goods['goods_sku']['goods_weight'], $goods_num, 2);
        // 当前用户收货城市id
        $defaultcity = Litestoreadress::getAddress($address_id);
        $cityId = $defaultcity ? $defaultcity['city_id'] : null;
        // 是否存在收货地址
        $exist_address = $defaultcity;
        // 验证用户收货地址是否存在运费规则中
        if (!$intraRegion = $goods['freight']->checkAddress($cityId)) {
            $exist_address && $this->setError('很抱歉，您的收货地址不在配送范围内');
        }
        $exchange_points = $goods['goods_sku']['exchange_points'] * $goods_num;
        // 计算配送费用
//        $expressPrice = $intraRegion ?
//            $goods['freight']->calcTotalFee($goods_num, $goods_total_weight, $cityId) : 0;
        $expressPrice = 0;
        $orderNo = $this->orderNo();

        return [
            'goods_list' => [$goods],               // 商品详情
            'order_total_num' => $goods_num,        // 商品总数量
            'order_total_price' => $totalPrice + $expressPrice,    // 商品总金额 (含运费)
            'order_total_points' => $exchange_points,
            'pay_price' => $totalPrice,  // 实际支付金额
            'address' => $defaultcity,  // 默认地址
            'exist_address' => $exist_address,  // 是否存在收货地址
            'express_price' => $expressPrice,    // 配送费用
            'intra_region' => $intraRegion,    // 当前用户收货城市是否存在配送规则中
            'has_error' => $this->hasError(),
            'error_msg' => $this->getError(),
            'pay_type' => $pay_type,
            'order_profit' => $goods['ratio'] * $totalPrice /100,
            'order_no' => $orderNo
        ];
    }


    public function order_money_add($user_id, $order)
    {
        if (empty($order['address'])) {
            $this->error = '请先选择收货地址';
            return false;
        }
        Db::startTrans();
        try {


            // 记录订单信息
            $order_id = $this->insertGetId([
                'user_id' => $user_id,
                'order_no' => $order['order_no'],
                'total_price' => $order['order_total_price'],
                'pay_price' => $order['pay_price'],
                'total_score' => 0,
                'express_price' => $order['express_price'],
                'pay_type' => $order['pay_type'],
                'order_type' => 'money',
                'order_profit' => $order['order_profit'],
                'createtime' => time(),
                'active_id' => $order['active_id']
            ]);
            // 订单商品列表
            $goodsList = [];
            // 更新商品库存 (下单减库存)
            $deductStockData = [];
            foreach ($order['goods_list'] as $goods) {
                /* @var Goods $goods */
                $goodsList[] = [
                    'user_id' => $user_id,
                    'goods_id' => $goods['goods_id'],
                    'goods_name' => $goods['goods_name'],
                    'images' => $goods['images'],
                    'deduct_stock_type' => $goods['deduct_stock_type'],
                    'spec_type' => $goods['spec_type'],
                    'spec_sku_id' => $goods['goods_sku']['spec_sku_id'],
                    'goods_spec_id' => $goods['goods_sku']['goods_spec_id'],
                    'goods_attr' => $goods['goods_sku']['goods_attr'],
                    'content' => $goods['content'],
                    'goods_no' => $goods['goods_sku']['goods_no'],
                    'goods_price' => $goods['goods_sku']['goods_price'],
                    'line_price' => $goods['goods_sku']['line_price'],
                    'goods_weight' => $goods['goods_sku']['goods_weight'],
                    'total_num' => $goods['total_num'],
                    'total_price' => $goods['total_price'],
                    'order_id' => $order_id
                ];
                // 下单减库存
                $goods['deduct_stock_type'] === '10' && $deductStockData[] = [
                    'goods_spec_id' => $goods['goods_sku']['goods_spec_id'],
                    'stock_num' => ['dec', $goods['total_num']]
                ];
            }
            // 保存订单商品信息
            $litestoreordergoods = new Litestoreordergoods();
            $litestoreordergoods->saveAll($goodsList);
            // 更新商品库存
            !empty($deductStockData) && (new Litestoregoodsspec)->isUpdate()->saveAll($deductStockData);
            // 记录收货地址

            $litestoreorderaddress = new Litestoreorderaddress();
            $litestoreorderaddress->save([
                'user_id' => $user_id,
                'order_id' => $order_id,
                'name' => $order['address']['name'],
                'phone' => $order['address']['phone'],
                'province_id' => $order['address']['province_id'],
                'city_id' => $order['address']['city_id'],
                'region_id' => $order['address']['region_id'],
                'detail' => $order['address']['detail'],
            ]);

//            //消费扣除
//            $desc = $userScoreModel->getLogTypeList()[2];
//            $userScoreModel->save(['user_id' => $user_id, 'score' => -$points,
//                'log_type' => 2, 'createtime' => time(), 'order_id' => $order_id, 'desc' => $desc]);

            Db::commit();

            return $order_id;
        } catch (Exception $exception) {
            Db::rollback();
            $this->error = $exception->getMessage();
            return false;
        }
    }


    public function order_add($user_id, $order)
    {
        if (empty($order['address'])) {
            $this->error = '请先选择收货地址';
            return false;
        }
        Db::startTrans();
        try {
            // 记录订单信息
            $order_id = $this->insertGetId([
                'user_id' => $user_id,
                'order_no' => $order['order_no'],
                'total_price' => $order['order_total_price'],
                'pay_price' => $order['pay_price'],
                'express_price' => $order['express_price'],
                'createtime' => time()

            ]);
            // 订单商品列表
            $goodsList = [];
            // 更新商品库存 (下单减库存)
            $deductStockData = [];
            foreach ($order['goods_list'] as $goods) {
                /* @var Goods $goods */
                $goodsList[] = [
                    'user_id' => $user_id,
                    'goods_id' => $goods['goods_id'],
                    'goods_name' => $goods['goods_name'],
                    'images' => $goods['images'],
                    'deduct_stock_type' => $goods['deduct_stock_type'],
                    'spec_type' => $goods['spec_type'],
                    'spec_sku_id' => $goods['goods_sku']['spec_sku_id'],
                    'goods_spec_id' => $goods['goods_sku']['goods_spec_id'],
                    'goods_attr' => $goods['goods_sku']['goods_attr'],
                    'content' => $goods['content'],
                    'goods_no' => $goods['goods_sku']['goods_no'],
                    'goods_price' => $goods['goods_sku']['goods_price'],
                    'line_price' => $goods['goods_sku']['line_price'],
                    'goods_weight' => $goods['goods_sku']['goods_weight'],
                    'total_num' => $goods['total_num'],
                    'total_price' => $goods['total_price'],
                    'order_id' => $order_id
                ];
                // 下单减库存
                $goods['deduct_stock_type'] === '10' && $deductStockData[] = [
                    'goods_spec_id' => $goods['goods_sku']['goods_spec_id'],
                    'stock_num' => ['dec', $goods['total_num']]
                ];
            }
            // 保存订单商品信息
            $litestoreordergoods = new Litestoreordergoods();
            $litestoreordergoods->saveAll($goodsList);
            // 更新商品库存
            !empty($deductStockData) && (new Litestoregoodsspec)->isUpdate()->saveAll($deductStockData);
            // 记录收货地址

            $litestoreorderaddress = new Litestoreorderaddress();
            $litestoreorderaddress->save([
                'user_id' => $user_id,
                'order_id' => $order_id,
                'name' => $order['address']['name'],
                'phone' => $order['address']['phone'],
                'province_id' => $order['address']['province_id'],
                'city_id' => $order['address']['city_id'],
                'region_id' => $order['address']['region_id'],
                'detail' => $order['address']['detail'],
            ]);



            Db::commit();

            return $order['order_no'];
        } catch (Exception $exception) {
            Db::rollback();
            $this->error = $exception->getMessage();
            return false;
        }
    }

    public function getPayStatusList()
    {
        return ['10' => __('Pay_status 10'), '20' => __('Pay_status 20')];
    }

    public function getFreightStatusList()
    {
        return ['10' => __('Freight_status 10'), '20' => __('Freight_status 20')];
    }

    public function getReceiptStatusList()
    {
        return ['10' => __('Receipt_status 10'), '20' => __('Receipt_status 20')];
    }

    public function getOrderStatusList()
    {
        return ['10' => __('Order_status 10'), '20' => __('Order_status 20'), '30' => __('Order_status 30')];
    }


    public function getPayStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['pay_status']) ? $data['pay_status'] : '');
        $list = $this->getPayStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getPayTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['pay_time']) ? $data['pay_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getFreightStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['freight_status']) ? $data['freight_status'] : '');
        $list = $this->getFreightStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getFreightTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['freight_time']) ? $data['freight_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getReceiptStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['receipt_status']) ? $data['receipt_status'] : '');
        $list = $this->getReceiptStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getReceiptTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['receipt_time']) ? $data['receipt_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getOrderStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['order_status']) ? $data['order_status'] : '');
        $list = $this->getOrderStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    public function getCreattimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['createtime']) ? $data['createtime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;;
    }

    protected function setPayTimeAttr($value)
    {
        return $value && !is_numeric($value) ? strtotime($value) : $value;
    }

    protected function setFreightTimeAttr($value)
    {
        return $value && !is_numeric($value) ? strtotime($value) : $value;
    }

    protected function setReceiptTimeAttr($value)
    {
        return $value && !is_numeric($value) ? strtotime($value) : $value;
    }

//    public function goods()
//    {
//        return $this->hasMany('Litestoreordergoods', 'order_id', 'id');
//    }

//    public function address()
//    {
//        return $this->hasOne('Litestoreorderaddress', 'order_id', 'id', [], 'LEFT')->setEagerlyType(0);
//    }

    private function setError($error)
    {
        empty($this->error) && $this->error = $error;
    }

    protected function orderNo()
    {
        return date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
    }

    public function hasError()
    {
        return !empty($this->error);
    }

    public function updatePayStatus($transaction_id)
    {
        Db::startTrans();
        // 更新商品库存、销量
        $GoodsModel = new Wxlitestoregoods;
        $GoodsModel->updateStockSales($this['goods']);
        // 更新订单状态
        $this->save([
            'pay_status' => '20',
            'pay_time' => time(),
            'transaction_id' => $transaction_id,
        ]);
        Db::commit();
        return true;
    }

    public function freeExchange($order_id){


        $this->where('id',$order_id)->update([
            'pay_status' => '20',
            'pay_time' => time()
        ]);

    }


}
